#include <conio.h>
#include "stack.h"
#include "FONT.H"
#include "INPUT.H"

//The scanline floodfill algorithm using our own stack routines, faster
void floodFillScanlineStack(int x, int y, int fill_color)
{
	Stack S;
	infotype P;
	infotype X;
    int tempY; 
	int target_color;
    boolean spanLeft, spanRight;
	
	target_color = getPixel(x,y);
    if(target_color == fill_color) return;
    CreateEmpty(&S);
    
	P.x = x;
	P.y = y;
    if(!PushFill(&S,P)) return;
    
    while(PopFill(&S,&P))
    {    
        tempY = P.y;
        while(tempY >= 0 && getPixel(P.x,tempY) == target_color) tempY--;
        tempY++;
        spanLeft = spanRight = 0;
        while(tempY < SCREEN_HEIGHT && getPixel(P.x,tempY) == target_color )
        {
            putPixel(P.x,tempY,fill_color);
            if(!spanLeft && P.x > 0 && getPixel(P.x-1,tempY) == target_color) 
            {
				X.x = P.x - 1;
				X.y = tempY;
                if(!PushFill(&S,X)) return;
                spanLeft = 1;
            }
            else if(spanLeft && P.x > 0 && getPixel(P.x-1,tempY) != target_color)
            {
                spanLeft = 0;
            }
            if(!spanRight && P.x < SCREEN_WIDTH - 1 && getPixel(P.x+1,tempY) == target_color) 
            {
				X.x = P.x + 1;
				X.y = tempY;
                if(!PushFill(&S,X)) return;
                spanRight = 1;
            }
            else if(spanRight && P.x < SCREEN_WIDTH - 1 && getPixel(P.x+1,tempY) != target_color)
            {
                spanRight = 0;
            } 
            tempY++;
        }
    }
}

int main()
{
	MouseState prevMouseState;
	MouseState currMouseState;
	MouseState tempMouseState;
	boolean mouseOn;
	boolean mouseClick = FALSE;
	int tInput;
	int drawType = 0;
	byte numButtons;
	byte fillColor = 0;
	Fonts fonts;
	boolean fontEnable = loadFonts("FONT.FNT", &fonts);
	int x0 = 0;
	int y0 = 0;
	int x1 = 0;
	int y1 = 0;
	int rad = 0;
	
	setMode(VGA_MODE);
	mouseOn = initMouse(&numButtons);	
	if(mouseOn){
		prevMouseState = getMouseState();
		showMouseCursor();
	}
	while(TRUE){
		setBackground(LIGHT_BLUE);
		if(mouseOn){
			currMouseState = getMouseState();
			if ((currMouseState.buttonState&1)==1) {
				if (!mouseClick) {
					tempMouseState = currMouseState;
					mouseClick = TRUE;
				}
				switch (drawType) {
					case 0:
						if (tempMouseState.x > currMouseState.x) {
							x0 = currMouseState.x;
							x1 = tempMouseState.x;
						} else {
							x1 = currMouseState.x;
							x0 = tempMouseState.x;
						}
						if (tempMouseState.y > currMouseState.y) {
							y0 = currMouseState.y;
							y1 = tempMouseState.y;
						} else {
							y1 = currMouseState.y;
							y0 = tempMouseState.y;
						}
						drawRectangle(x0,y0,x1,y1, BLUE);
						break;
					case 1:
						if (tempMouseState.x > currMouseState.x) {
							rad = (tempMouseState.x - currMouseState.x) / 2;
						} else {
							rad = (currMouseState.x - tempMouseState.x) / 2;
						}
						drawCircle(tempMouseState.x,tempMouseState.y,rad,BLUE);
						break;
					case 2:
						// if (tempMouseState.x > currMouseState.x) {
							// x0 = currMouseState.x;
							// x1 = tempMouseState.x;
						// } else {
							// x1 = currMouseState.x;
							// x0 = tempMouseState.x;
						// }
						// if (tempMouseState.y > currMouseState.y) {
							// y0 = currMouseState.y;
							// y1 = tempMouseState.y;
						// } else {
							// y1 = currMouseState.y;
							// y0 = tempMouseState.y;
						// }
						drawLine(tempMouseState.x,tempMouseState.y,currMouseState.x,currMouseState.y, BLUE);
						break;
				}
			}
			if (((prevMouseState.buttonState&1)==1) && ((currMouseState.buttonState&1)==0)) {
				mouseClick = FALSE;
			}
			prevMouseState = currMouseState;
		}
		if(kbhit()){
			tInput = getKey();
			/* Escape to quit*/
			if(tInput == 27){
				break;
			}	
			switch(tInput) {
				case 97:
					drawType = 0;
					break;
				case 98:
					drawType = 1;
					break;
				case 99:
					drawType = 2;
					break;
			}
		}
		redraw();		
		delay(33);
	}	
	setMode(TEXT_MODE);
	return EXIT_SUCCESS;
}